//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
//
// (C) Copyright 2006 Marvell International Ltd.
// All Rights Reserved
//

#ifndef __PDD_PRIVATE_H__
#define __PDD_PRIVATE_H__

#include <windows.h>
#include <ceddk.h>
#include <pm.h>

#include "Cs.h"
#include "Csmedia.h"

#include "CameraPDDProps.h"
#include "dstruct.h"
#include "dbgsettings.h"
#include <camera.h>
#include "CameraDriver.h"
#include "PinDriver.h"

#include "CameraPDD.h"
#include "ipm_api.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef MMRESULT (WINAPI *FNTIMEKILLEVENT)(UINT);
typedef MMRESULT (WINAPI *FNTIMESETEVENT)(UINT, UINT, LPTIMECALLBACK, DWORD, UINT );

#include "qci.h"
#include "sensor.h"

typedef class CCameraPdd
{
public:
    
    friend class CCameraDevice;

    CCameraPdd();

    ~CCameraPdd();

    DWORD PDDInit( 
        PVOID MDDContext,
        PPDDFUNCTBL pPDDFuncTbl
        );

    DWORD GetAdapterInfo( 
        PADAPTERINFO pAdapterInfo 
        );

    DWORD HandleVidProcAmpChanges(
        DWORD dwPropId, 
        LONG lFlags, 
        LONG lValue
        );
    
    DWORD HandleCamControlChanges( 
        DWORD dwPropId, 
        LONG lFlags, 
        LONG lValue 
        );

    DWORD HandleVideoControlCapsChanges(
        LONG lModeType ,
        ULONG ulCaps 
        );

    DWORD SetPowerState(
        CEDEVICE_POWER_STATE PowerState 
        );
    
    DWORD HandleAdapterCustomProperties(
        PUCHAR pInBuf, 
        DWORD  InBufLen, 
        PUCHAR pOutBuf, 
        DWORD  OutBufLen, 
        PDWORD pdwBytesTransferred 
        );

    DWORD InitSensorMode(
        ULONG ulModeType, 
        LPVOID ModeContext
        );
    
    DWORD DeInitSensorMode( 
        ULONG ulModeType 
        );

    DWORD SetSensorState( 
        ULONG lPinId, 
        CSSTATE csState 
        );

	void set_flashlight(bool is_on);

    DWORD TakeStillPicture(
        LPVOID pBurstModeInfo );

    DWORD GetSensorModeInfo( 
        ULONG ulModeType, 
        PSENSORMODEINFO pSensorModeInfo 
        );

    DWORD SetSensorModeFormat( 
        ULONG ulModeType, 
        PCS_DATARANGE_VIDEO pCsDataRangeVideo 
        );

    PVOID AllocateBuffer(
        ULONG ulModeType 
        );

    DWORD DeAllocateBuffer( 
        ULONG ulModeType, 
        PVOID pBuffer
        );

    DWORD RegisterClientBuffer(
        ULONG ulModeType, 
        PVOID pBuffer 
        );

    DWORD UnRegisterClientBuffer( 
        ULONG ulModeType, 
        PVOID pBuffer 
        );

    DWORD FillBuffer( 
        ULONG ulModeType, 
        PUCHAR pImage );

    DWORD HandleSensorModeCustomProperties( 
        ULONG ulModeType, 
        PUCHAR pInBuf, 
        DWORD  InBufLen, 
        PUCHAR pOutBuf, 
        DWORD  OutBufLen, 
        PDWORD pdwBytesTransferred 
        );

    static
    void
    CaptureInterruptCallBack(
        ULONG user,
        ULONG mode
        ); 

    frame_t* qci_frame;
private:

    void 
    HandleCaptureInterrupt( ULONG mode );

    DWORD 
    YUVBufferFill( ULONG ulModeType, PUCHAR pImage );

    bool 
    ReadMemoryModelFromRegistry();

    bool
    detect_sensor();
    
    bool 
    detect_disable_sensor5623(Sensor *pSensor5623);
  
    BOOL
    prepare_format(PCS_VIDEOINFOHEADER pCsVideoInfoHdr, ULONG mode);

    void
    set_capture_format(int sensor_format,
                       FrameSize sensor_size,
                       format_t* qci_format);

    void
    start_capture(ULONG mode);

    void
    stop_capture();

    void 
    qci_clock_enable(BOOL is_on);

    void
    qci_enable();

    void
    qci_start_capture(int still_skips);

    void
    qci_stop_capture();

    void
    qci_set_master_timing(qci_master_timing_t* timing);

    void
    qci_set_image_format(int in_format, 
                         int out_format);

    void 
    qci_set_interface(qci_interface_t* qci_interface);

    void
    qci_set_capture_callback(capture_callback_t callback, ULONG user, ULONG mode);

    void
    qci_notify_formats(format_t* format);

    void
    qci_set_frame_format(format_t* format);

    void
    qci_set_image_proc_cfg(qci_image_proc_cfg_t* cfg);

    void
    power_on();

    void
    power_off();

    void 
    init_ipm_client();

    void
    set_ipm_block(BOOL is_on);

private:

    bool    m_bStillCapInProgress;
    HANDLE m_hContext;
    
    CSSTATE                 m_CsState[MAX_SUPPORTED_PINS];
    SENSORMODEINFO           m_SensorModeInfo[MAX_SUPPORTED_PINS];

    // Total number of pins implemented by this camera
    ULONG m_ulCTypes;

    // Power Capabilities
    POWER_CAPABILITIES PowerCaps; 

    // All ProcAmp and CameraControl props
    SENSOR_PROPERTY     m_SensorProps[NUM_PROPERTY_ITEMS];

    // All the Video Formats supported by all the pins
    PPINVIDEOFORMAT   m_pModeVideoFormat;

    // VideoControl Caps corresponding to all the pins
    VIDCONTROLCAPS   *m_pModeVideoCaps;

    // Pointer to the MDD Pin Object corresponding to all the pins.
    // HandlePinIO() method of this object is then called whenever 
    // an image is ready. HandlePinIO() internally calls 
    // FillPinBuffer() of PDD interface.
    LPVOID       *m_ppModeContext;
    
    // Currently selected video format for each pin
    PCS_DATARANGE_VIDEO m_pCurrentFormat;

    Sensor* sensor;
    
    camera_cfg_t* camera_cfg;
    HANDLE qci_bus;
    BOOL is_qci_capturing;
    BOOL is_sensor_on;
    BOOL is_ipm_enabled;
    CLIENT_ID ipm_client_id;
    unsigned ipm_block_ref_count;
} CAMERAPDD, * PCAMERAPDD;

IppiRawPixProcSpec_P3R *rggb2yuv_init(unsigned int width, 
                                      unsigned int height, 
                                      format_t* qci_format, 
                                      float* coe);
BOOL rggb2yuv_convert(PUCHAR* dest, frame_t* frame, IppiRawPixProcSpec_P3R *ippiRPPSpec);
void rggb2yuv_deinit(IppiRawPixProcSpec_P3R *ippiRPPSpec);
void convert_rggb10_rgb565(unsigned short *dst, unsigned short *src, 
			  unsigned int dst_width, unsigned int dst_height,
			  unsigned int src_width, unsigned int src_height);

#define IPP_COE_CONVERT(x)   ((short)((x) * (1UL << 8) + 0.5))
#define QCI_COE_CONVERT(x)   (((short)((x) * (1UL << 7))) & 0x3ff)

#ifdef __cplusplus
}
#endif

#endif
